//---------------------------------------------------------------------
// <copyright file="Command.cs" company="Microsoft">
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//---------------------------------------------------------------------

namespace EFOracleOdpProvider
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Common;
    using System.Data.Metadata.Edm;
    using System.Diagnostics;
    using System.IO;
    using System.Text;
    using Oracle.DataAccess;
    using Oracle.DataAccess.Client;

    public partial class EFOracleOdpCommand : DbCommand, ICloneable
    {
        #region Private Fields

        private OracleCommand _product = new OracleCommand();        

        private PrimitiveType[] _expectedColumnTypes;

        private EFOracleOdpConnection _connection = null;

        private DbTransaction _transaction = null;

        private bool _designTimeVisible = true;

        private static TextWriter _log = TextWriter.Null;

        #endregion

        #region Initialization

        public EFOracleOdpCommand()
        {
            this.CommandType = CommandType.Text;
        }

        public EFOracleOdpCommand(string commandText)
            : this()
        {
            InitializeMe(commandText, null, null);
        }

        public EFOracleOdpCommand(string commandText, EFOracleOdpConnection connection)
            : this()
        {
            InitializeMe(commandText, connection, null);
        }

        public EFOracleOdpCommand(string commandText, EFOracleOdpConnection connection, DbTransaction transaction)
            : this()
        {
            InitializeMe(commandText, connection, transaction);
        }

        private void InitializeMe(string commandText, EFOracleOdpConnection connection, DbTransaction transaction)
        {
            CommandText = commandText;
            Connection = connection;
            Transaction = transaction;
        }

        #endregion

        #region Properties

        public override string CommandText
        {
            get { return _product.CommandText; }
            set { _product.CommandText = value; }
        }

        public override int CommandTimeout
        {
            get { return _product.CommandTimeout; }
            set { _product.CommandTimeout = value; }
        }

        public override CommandType CommandType
        {
            get { return _product.CommandType; }
            set { _product.CommandType = value; }
        }

        public override bool DesignTimeVisible
        {
            get { return _designTimeVisible; }
            set { _designTimeVisible = value; }
        }

        internal PrimitiveType[] ExpectedColumnTypes
        {
            get { return _expectedColumnTypes; }
            set { _expectedColumnTypes = value; }
        }

        public static TextWriter Log
        {
            get { return _log; }
            set { _log = value ?? TextWriter.Null; }
        }

        #endregion

        #region Methods

        public override void Cancel()
        {
            _product.Cancel();
        }

        protected override DbParameter CreateDbParameter()
        {
            return new OracleParameter();
        }
        
        protected override DbConnection DbConnection
        {
            get { return _connection; }
            set
            {
                _connection = (EFOracleOdpConnection) value;
                _product.Connection = _connection.OracleConnection;
            }
        }

        protected override DbParameterCollection DbParameterCollection
        {
            get { return _product.Parameters; }
        }
        
        protected override DbTransaction DbTransaction
        {
            get { return _transaction; }
            set
            {
                _transaction = value;
                ((DbCommand) _product).Transaction = _transaction;
            }
        }

        public override int ExecuteNonQuery()
        {
            DumpQuery();
            return _product.ExecuteNonQuery();
        }

        public override object ExecuteScalar()
        {
            DumpQuery();
            return _product.ExecuteScalar();
        }

        protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
        {
            DumpQuery();
            return new EFOracleOdpDataReader(this, _product.ExecuteReader(behavior), ExpectedColumnTypes);
        }

        private void DumpQuery()
        {
            
            Log.WriteLine("{0}", CommandText);
        }

        public override void Prepare()
        {
            _product.Prepare();
        }

        public override UpdateRowSource UpdatedRowSource
        {
            get { return _product.UpdatedRowSource; }
            set { _product.UpdatedRowSource = value; }
        }

        #endregion

        #region ICloneable

        object ICloneable.Clone()
        {
            EFOracleOdpCommand clone = new EFOracleOdpCommand();

            clone._connection = _connection;
            clone.ExpectedColumnTypes = _expectedColumnTypes;
            clone._product =  (OracleCommand) ((ICloneable)_product).Clone();

            return clone;
        }

        #endregion
    }
}
